package com.atgouwu.mall.product.service.impl;

import com.atgouwu.mall.product.vo.CatelogTwoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atgouwu.mall.common.utils.PageUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.atgouwu.mall.product.dao.CategoryDao;
import com.atgouwu.mall.product.entity.CategoryEntity;
import com.atgouwu.mall.product.service.CategoryService;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

@Service("categoryService")
@Transactional(isolation = Isolation.DEFAULT)
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {
    @Autowired
    private CategoryDao categoryDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CategoryEntity> page = this.page(
                new Page<>(Long.valueOf(String.valueOf(params.get("page"))), Long.valueOf(String.valueOf(params.get("size")))),
                new QueryWrapper<CategoryEntity>()
        );
        return new PageUtils(page.getRecords(), (int) page.getTotal(), (int) page.getSize(), (int) page.getCurrent());
    }

    //获取所有一级分类
    @Cacheable(value = {"category"}, key = "#root.method.name", sync = true)
    @Override
    public List<CategoryEntity> getLevelOneCategory() {
        List<CategoryEntity> categoryEntities = baseMapper.selectList(new QueryWrapper<CategoryEntity>().eq("parent_cid", 0));
        return categoryEntities;
    }

    //获取三级分类{一级分类id:二三级分类对象}
    @Cacheable(value = "category", key = "#root.methodName")
    @Override
    public Map<String, List<CatelogTwoVo>> getCatalogJson() {
        List<CategoryEntity> selectList = baseMapper.selectList(null); //查出所有分类
        List<CategoryEntity> levelOneCategorys = getParent_cid(selectList, 0L); //筛选出一级分类
        Map<String, List<CatelogTwoVo>> categoryMap = levelOneCategorys.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> { //封装一级分类
            List<CategoryEntity> categoryEntities = getParent_cid(selectList, v.getCatId()); //筛选出二级分类
            List<CatelogTwoVo> catelogTwoVos = null;
            if (categoryEntities != null) {
                catelogTwoVos = categoryEntities.stream().map(l2 -> {
                    CatelogTwoVo catelogTwoVo = new CatelogTwoVo(v.getCatId().toString(), l2.getCatId().toString(), l2.getName().toString(), null); //封装二级分类
                    List<CategoryEntity> levelThreeCatelog = getParent_cid(selectList, l2.getCatId()); //筛选出三级分类
                    if (levelThreeCatelog != null) {
                        List<CatelogTwoVo.CategoryThreeVo> categoryThreeVos = levelThreeCatelog.stream().map(l3 -> { //封装三级分类
                            CatelogTwoVo.CategoryThreeVo categoryThreeVo = new CatelogTwoVo.CategoryThreeVo(l2.getCatId().toString(), l3.getCatId().toString(), l3.getName());
                            return categoryThreeVo;
                        }).collect(Collectors.toList());
                        catelogTwoVo.setCatalogThreeList(categoryThreeVos);
                    }
                    return catelogTwoVo;
                }).collect(Collectors.toList());
            }
            return catelogTwoVos;
        }));
        return categoryMap;
    }

    //根据父分类id筛选出当前分类
    private List<CategoryEntity> getParent_cid(List<CategoryEntity> selectList, Long parentCid) {
        return selectList.stream().filter(item -> item.getParentCid().equals(parentCid)).collect(Collectors.toList());
    }

    //获取三级分类列表
    @Override
    public List<CategoryEntity> listWithTree() {
        List<CategoryEntity> entities = baseMapper.selectList(null); //查出所有分类
        List<CategoryEntity> levelMenus = entities.stream().filter(e -> e.getParentCid() == 0).map((menu) -> { //组装成父子树形结构
            menu.setChildren(getChildrens(menu, entities));
            return menu;
        }).sorted((menu, menu2) -> { //排序
            return (menu.getSort() == null ? 0 : menu.getSort()) - (menu2.getSort() == null ? 0 : menu2.getSort());
        }).collect(Collectors.toList());
        return levelMenus;
    }

    //递归查找所有分类的子分类
    private List<CategoryEntity> getChildrens(CategoryEntity root, List<CategoryEntity> all) {
        List<CategoryEntity> children = all.stream().filter(categoryEntity -> { //子分类
            return categoryEntity.getParentCid().equals(root.getCatId());
        }).map(categoryEntity -> {
            categoryEntity.setChildren(getChildrens(categoryEntity, all)); //继续递归找到孙子分类
            return categoryEntity;
        }).sorted((menu, menu2) -> { //排序
            return (menu.getSort() == null ? 0 : menu.getSort()) - (menu2.getSort() == null ? 0 : menu2.getSort());
        }).collect(Collectors.toList());
        return children;
    }

    //获取分类路径
    @Override
    public Long[] findCatelogPath(Long catelogId) {
        List<Long> paths = new ArrayList<>();
        List<Long> parentPath = findParentPath(catelogId, paths); //递归查询是否还有父节点
        Collections.reverse(parentPath); //进行一个逆序排列
        return (Long[]) parentPath.toArray(new Long[parentPath.size()]);
    }

    //递归查询是否还有父节点
    private List<Long> findParentPath(Long catelogId, List<Long> paths) {
        paths.add(catelogId); //收集当前节点id
        CategoryEntity byId = this.getById(catelogId); //根据当前分类id查询信息
        if (byId.getParentCid() != 0) { //如果当前不是父分类
            findParentPath(byId.getParentCid(), paths);
        }
        return paths;
    }

    //根据分类名称获取分类id
    @Override
    public List<Long> getCategoryIdByName(String catalogNames) {
        //List<Long> categoryIdList = categoryDao.getCategoryIdByName(catalogNames.split(","));
        List<CategoryEntity> categoryList = baseMapper.selectList(new QueryWrapper<CategoryEntity>().select("cat_id").in("name", catalogNames.split(",")));
        List<Long> categoryIdList = categoryList.stream().map(CategoryEntity::getCatId).collect(Collectors.toList());
        return categoryIdList;
    }

}